package com.bedrock.project.inside.service.impl;

import com.alibaba.fastjson.JSON;
import com.bedrock.common.constant.ProjectConstants;
import com.bedrock.common.utils.DateUtils;
import com.bedrock.common.utils.SecurityUtils;
import com.bedrock.common.utils.bean.BeanUtils;
import com.bedrock.framework.aspectj.lang.annotation.DataScope;
import com.bedrock.framework.interceptor.annotation.RepeatSubmit;
import com.bedrock.framework.security.LoginUser;
import com.bedrock.framework.web.page.TableDataInfo;
import com.bedrock.project.inside.entity.ProjectInfo;
import com.bedrock.project.inside.entity.ProjectUserInfo;
import com.bedrock.project.inside.mapper.ProjectInfoMapper;
import com.bedrock.project.inside.mapper.ProjectUserInfoMapper;
import com.bedrock.project.inside.service.IProjectInfoService;
import com.bedrock.project.inside.service.WorkHourService;
import com.bedrock.project.inside.vo.request.ProjectInfoReqVo;
import com.bedrock.project.inside.vo.response.ProjectIdAndNameResVo;
import com.bedrock.project.inside.vo.response.ProjectInfoResVo;
import com.bedrock.project.system.domain.SysRole;
import com.bedrock.project.system.service.ISysUserService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 项目信息Service业务层处理
 * 
 * @author bedrock
 * @date 2020-04-07
 */
@Service
public class ProjectInfoServiceImpl implements IProjectInfoService
{
    @Autowired
    private ProjectInfoMapper projectInfoMapper;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ProjectUserInfoMapper projectUserInfoMapper;

    @Autowired
    private WorkHourService workHourService;

    protected final Logger logger = LoggerFactory.getLogger(ProjectInfoServiceImpl.class);

    /**
     * 查询项目信息
     * 
     * @param projectId 项目信息ID
     * @return 项目信息
     */
    @Override
    public ProjectInfo selectProjectInfoById(Long projectId)
    {
        return projectInfoMapper.selectProjectInfoById(projectId);
    }

    /**
     * 查询项目信息
     *
     * @param projectId 项目信息ID
     * @return 项目信息
     */
    @Override
    public ProjectInfoResVo selectProjectVoInfoById(Long projectId)
    {
        ProjectInfo projectInfo = new ProjectInfo();
        projectInfo.setProjectId(projectId);
        List<ProjectInfo> list = this.selectProjectInfoList(projectInfo);
        List<ProjectInfoResVo> result = beanToVo(list);
        if(CollectionUtils.isNotEmpty(result)) {
            return result.get(0);
        }
        return null;
    }

    /**
     * 查询项目信息列表
     *
     * @param
     * @return 项目信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<ProjectInfo> selectProjectInfoList(ProjectInfo projectInfo)
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUser().getUserId();
        List<SysRole> roleList = loginUser.getUser().getRoles();
        logger.info("用户的权限key列表为{}", JSON.toJSONString(roleList));
        // 权限校验
        List<String> roleKeyList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(roleList)){
            for (SysRole sysRole : roleList) {
                roleKeyList.add(sysRole.getRoleKey());
            }
        }else{
            return Collections.EMPTY_LIST;
        }
        //部门主管或admin查看所有
        if(roleKeyList.contains(ProjectConstants.ROLE_KEY_PMO)||roleKeyList.contains(ProjectConstants.ROLE_KEY_ADMIN)){
        }
        else if(roleKeyList.contains(ProjectConstants.ROLE_KEY_PM)){
            projectInfo.setPrincipalId(userId);
        }
        else if(roleKeyList.contains(ProjectConstants.ROLE_KEY_SALESMAN)){
            projectInfo.setSalemanId(userId);
        }else{
            ArrayList<ProjectUserInfo> userList = new ArrayList<>();
            ProjectUserInfo projectUserInfo = new ProjectUserInfo();
            projectUserInfo.setUserId(userId);
            userList.add(projectUserInfo);
            projectInfo.setMember(userList);
        }

        return projectInfoMapper.selectProjectInfoList(projectInfo);
    }


    /**
     * 新增项目信息
     * 
     * @param projectInfoReqVo 项目信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @RepeatSubmit
    public int insertProjectInfo(ProjectInfoReqVo projectInfoReqVo)
    {
        //保存项目主表
        ProjectInfo projectInfo = new ProjectInfo();
        BeanUtils.copyBeanProp(projectInfo,projectInfoReqVo);
        projectInfo.setDeptId(SecurityUtils.getLoginUser().getUser().getDeptId());
        projectInfo.setCreateTime(DateUtils.getNowDate());
        projectInfo.setCreateBy(SecurityUtils.getUsername());
        int row = projectInfoMapper.insertProjectInfo(projectInfo);
        //获取到projectId
        Long projectId = projectInfoMapper.selectProjectId(projectInfo.getProjectName());
        //保存成员关联表
        this.insertToMember(projectInfoReqVo,projectId);
        return row;
    }

    private void insertToMember(ProjectInfoReqVo projectInfoReqVo,Long projectId) {
        List<ProjectUserInfo> member = projectInfoReqVo.getMember();
        if(CollectionUtils.isNotEmpty(member)){
            for (ProjectUserInfo projectUserInfo : member) {
                projectUserInfo.setProjectId(projectId);
                //由于前端传过来的真实姓名为nickName,所以保存在数据库需要将userName赋值为nickName
                projectUserInfo.setUserName(projectUserInfo.getNickName());
                projectUserInfoMapper.insertProjectUserInfo(projectUserInfo);
            }
        }
    }

    /**
     * 修改项目信息
     * 
     * @param projectInfoReqVo 项目信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @RepeatSubmit
    public int updateProjectInfo(ProjectInfoReqVo projectInfoReqVo)
    {
        //删除旧成员关联
        projectUserInfoMapper.deleteProjectUserInfoById(projectInfoReqVo.getProjectId());
        //更新项目主表
        ProjectInfo projectInfo = new ProjectInfo();
        BeanUtils.copyBeanProp(projectInfo,projectInfoReqVo);
        projectInfo.setUpdateBy(SecurityUtils.getUsername());
        projectInfo.setUpdateTime(DateUtils.getNowDate());
        int row = projectInfoMapper.updateProjectInfo(projectInfo);
        //保存项目主表
        this.insertToMember(projectInfoReqVo,projectInfoReqVo.getProjectId());
        return row;
    }

    /**
     * 批量删除项目信息
     * 
     * @param projectIds 需要删除的项目信息ID
     * @return 结果
     */
    @Override
    public int deleteProjectInfoByIds(Long[] projectIds)
    {
        return projectInfoMapper.deleteProjectInfoByIds(projectIds);
    }

    /**
     * 删除项目信息信息
     * 
     * @param projectId 项目信息ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteProjectInfoById(Long projectId)
    {
        //删除关联表信息
        projectUserInfoMapper.deleteProjectUserInfoById(projectId);
        //删除主表信息
        return projectInfoMapper.deleteProjectInfoById(projectId);
    }

    /**
     * 校验项目名称是否唯一
     *
     * @param projectInfoReqVo 项目名称
     * @return 结果
     */
    @Override
    public String checkProjectNameUnique(ProjectInfoReqVo projectInfoReqVo) {
        int count = projectInfoMapper.checkProjectNameUnique(projectInfoReqVo.getProjectName(),projectInfoReqVo.getProjectId());
        if (count > 0)
        {
            return ProjectConstants.NOT_UNIQUE;
        }
        return ProjectConstants.UNIQUE;
    }

    /**
     * 校验项目状态
     *
     * @param projectInfo 项目
     * @return 结果
     */
    @Override
    public boolean checkProjectDeletableByStatus(ProjectInfo projectInfo) {
        //校验状态为废弃才能被删除
        if(ProjectConstants.PMP_PROJECT_STATUS_DISCARDED.equals(projectInfo.getProjectStatus())){
            return true;
        }
        return false;
    }

    /**
     * 检查项目可删除权限  部门主管或销售可修改
     * @return
     */
    @Override
    public boolean checkProjectDeletableByRole(ProjectInfo projectInfo) {
        //部门主管或admin可删除
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SysRole> roleList = loginUser.getUser().getRoles();
        logger.info("用户的权限key列表为{}", JSON.toJSONString(roleList));
        if(CollectionUtils.isNotEmpty(roleList)){
            for (SysRole sysRole : roleList) {
                if(sysRole.getRoleKey().equals(ProjectConstants.ROLE_KEY_PMO)||sysRole.getRoleKey().equals(ProjectConstants.ROLE_KEY_ADMIN)){
                    return true;
                }
            }
        }
        return false;
    }


    @Override
    public boolean checkProjectRevisableByStatus(ProjectInfo projectInfo) {
        //校验状态为已关闭和废弃不能被修改
        if(ProjectConstants.PMP_PROJECT_STATUS_DISCARDED.equals(projectInfo.getProjectStatus())||
                ProjectConstants.PMP_PROJECT_STATUS_CLOSED.equals(projectInfo.getProjectStatus())){
            return false;
        }
        return true;
    }

    /**
     * 检查项目可修改权限  部门主管或admin可修改  销售仅可以修改自己的项目
     * @return
     */
    @Override
    public boolean checkProjectRevisableByRole(ProjectInfo projectInfo) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SysRole> roleList = loginUser.getUser().getRoles();
        logger.info("用户的权限key列表为{}", JSON.toJSONString(roleList));
        List<String> roleKeyList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(roleList)){
            for (SysRole sysRole : roleList) {
                roleKeyList.add(sysRole.getRoleKey());
            }
        }
        //部门主管或admin可修改
        if(roleKeyList.contains(ProjectConstants.ROLE_KEY_PMO)||roleKeyList.contains(ProjectConstants.ROLE_KEY_ADMIN)){
            return true;
        }
        //销售仅可以修改自己的项目
        if(roleKeyList.contains(ProjectConstants.ROLE_KEY_SALESMAN)&&projectInfo.getSalemanId().equals(loginUser.getUser().getUserId())){
            return true;
        }
        return false;
    }

    /**
     * 转换page对象
     * @param dataTable
     */
    @Override
    public TableDataInfo convert(TableDataInfo dataTable) {
        List<ProjectInfo> list = (List<ProjectInfo>) dataTable.getRows();
        dataTable.setRows(beanToVo(list));
        return dataTable;
    }

    @Override
    public List<ProjectIdAndNameResVo> selectActiveProjectByDevelopers(List<String> excludeProjectStatus) {
        Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
        return projectInfoMapper.selectActiveProjectByDevelopers(excludeProjectStatus,userId);
    }

    @Override
    public boolean checkProjectDeletableByWorkHour(ProjectInfo projectInfo) {
        boolean workHourExist = workHourService.checkWorkHourByProject(projectInfo.getProjectId());
        if(workHourExist){
            return true;
        }
        return false;
    }

    private List<ProjectInfoResVo> beanToVo(List<ProjectInfo> list) {
        List<ProjectInfoResVo> result = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(list)) {
            for (ProjectInfo info : list) {
                ProjectInfoResVo bean = new ProjectInfoResVo();
                BeanUtils.copyBeanProp(bean, info);
                bean.setMember(projectUserInfoMapper.selectProjectUserInfoById(info.getProjectId()));
                result.add(bean);
            }
            list.clear();
        }
        return result;
    }


}
